package com.example.lte.service;

import com.example.lte.entity.RoleEntity;
import com.example.lte.entity.RoleUserEntity;
import com.example.lte.repo.RoleRepo;
import com.example.lte.repo.RoleUserRelRepo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements IRoleService {
    @Resource
    private RoleRepo roleRepo;
    @Resource
    private RoleUserRelRepo roleUserRelRepo;

    @Override
    public List<RoleEntity> getRoleEnum() {
        return roleRepo.findAll();
    }

    @Override
    public RoleEntity findById(Long id) {
        return roleRepo.findById(id).orElse(null);
    }

    /**
     * 分页查询角色
     *
     * @param roleEntity RoleEntity
     * @param pageable   Pageable
     * @return Page<RoleEntity>
     */
    @Override
    public Page<RoleEntity> findByCondition(RoleEntity roleEntity, Pageable pageable) {
        return roleRepo.findAll((root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (!StringUtils.isEmpty(roleEntity.getId())) {
                predicates.add(cb.equal(root.get("id"), roleEntity.getId()));
            }
            if (!StringUtils.isEmpty(roleEntity.getName())) {
                predicates.add(cb.equal(root.get("name"), roleEntity.getName()));
            }
            if (!StringUtils.isEmpty(roleEntity.getNote())) {
                predicates.add(cb.like(root.get("note"), "%" + roleEntity.getNote() + "%"));
            }
            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
    }

    /**
     * 获取用户关联的角色，（用户表格展开行显示角色时使用）
     *
     * @param userId Long
     * @return List<RoleEntity>
     */
    @Override
    public List<RoleEntity> getRelRoleByUserId(Long userId) {
        List<RoleUserEntity> rel = roleUserRelRepo.findByUserId(userId);
        if (!CollectionUtils.isEmpty(rel)) {
            List<Long> relRoleIds = rel.stream().map(RoleUserEntity::getRoleId).collect(Collectors.toList());
            return roleRepo.findByIdIn(relRoleIds);
        }
        return new ArrayList<>();
    }

    /**
     * 统计用户挂的角色数
     *
     * @param userId 用户id
     * @return int 用户挂的角色数
     */
    @Override
    public int countRoleUserByUserId(Long userId) {
        List<RoleUserEntity> roleUserEntities = roleUserRelRepo.findByUserId(userId);
        if (CollectionUtils.isEmpty(roleUserEntities)) {
            return 0;
        } else {
            return roleUserEntities.size();
        }
    }

    @Override
    public void delByUserIds(Long[] userIds) {
        roleUserRelRepo.deleteByUserIds(userIds);
    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOneRole(RoleEntity roleEntity) {
        roleRepo.save(roleEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOneRole(RoleEntity roleEntity) {
        roleRepo.save(roleEntity);
    }

    /**
     * 用户添加角色关系
     *
     * @param roleIds Long[]
     * @param userId  Long
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRelRoleIds(Long[] roleIds, Long userId) {
        roleUserRelRepo.deleteByUserIds(new Long[]{userId});
        List<RoleUserEntity> saveData = new ArrayList<>();
        for (Long roleId : roleIds) {
            saveData.add(RoleUserEntity.builder().userId(userId).roleId(roleId).build());
        }
        roleUserRelRepo.saveAll(saveData);
    }
}
